﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using Ext.Net;
using System.ComponentModel;
using System.IO;
using Newtonsoft.Json;
using System.Xml.Serialization;

namespace Sio.Mdm.Web.Controls
{
    [Meta]
    public class Dialog : Window
    {
        public Dialog()
            : this(null)
        {
        }

        public Dialog(string url)
            : this(url, DialogButtons.None)
        {

        }

        public Dialog(string url, DialogButtons buttons)
        {
            Hidden = true;
            Width = 500;
            Height = 350;
            DialogButtons = buttons;
            Url = url;
            Modal = true;
            CloseAction = CloseAction.Close;
            Title = String.Empty;
        }

        private string url;
        [Meta]
        [ConfigOption]
        public string Url
        {
            get
            {
                return url;
            }
            set
            {
                url = value;
            }
        }

        private DialogButtons buttons = DialogButtons.Ok;
        [Meta]
        [ConfigOption]
        public DialogButtons DialogButtons
        {
            get
            {
                return buttons;
            }
            set
            {
                buttons = value;
            }
        }

        [Description("Parameters to pass to page loaded into body.")]
        [ConfigOption(JsonMode.ArrayToObject)]
        [NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ParameterCollection Parameters
        {
            get
            {
                return AutoLoad.Params;
            }
        }

        [Meta]
        [JsonIgnore]
        [XmlIgnore]
        public override ConfigOptionsCollection ConfigOptions
        {
            get
            {
                ConfigOptionsCollection list = base.ConfigOptions;

                list.Add("url", new ConfigOption("url", new SerializationOptions("url"), null, this.Url));
                list.Add("butons", new ConfigOption("buttons", new SerializationOptions("buttons"), DialogButtons.Ok, this.DialogButtons));

                return base.ConfigOptions;
            }
        }

        protected override void EnsureChildControls()
        {

            base.EnsureChildControls();
        }
        protected override void OnLoad(EventArgs e)
        {   
            RenderButtons();
            base.OnLoad(e);
        }
        protected override void OnPreRender(EventArgs e)
        {
            if (!ExtNet.IsAjaxRequest)
            {
                if (String.IsNullOrEmpty(url))
                {
                    throw new ArgumentNullException("Url");
                }

                AutoLoad.Mode = LoadMode.IFrame;
                AutoLoad.Url = Url;
            }

            base.OnPreRender(e);
        }

        public void AddParameter(Ext.Net.Parameter parameter)
        {
            if (ExtNet.IsAjaxRequest)
            {
                this.Call("addParameter", parameter.Name, parameter.Value);
            }
            else
            {
                AutoLoad.Params.Add(parameter);
            }
        }

        public override void Render()
        {
            base.Render();
        }

        private void RenderButtons()
        {
            if ((DialogButtons & DialogButtons.Ok) == DialogButtons.Ok)
            {
                Buttons.Add(new DialogButton(new DialogButton.Config()
                {
                    Text = "Potrdi",
                    Icon = Icon.Accept,
                    ButtonType = DialogButtons.Ok,
                    ID = String.Format("{0}Ok", ID)
                }));
            }



            if ((DialogButtons & DialogButtons.Yes) == DialogButtons.Yes)
            {
                Buttons.Add(new DialogButton(new DialogButton.Config()
                {
                    Text = "Da",
                    Icon = Icon.Accept,
                    ButtonType = DialogButtons.Yes,
                    ID = String.Format("{0}Yes", ID)
                }));
            }

            if ((DialogButtons & DialogButtons.No) == DialogButtons.No)
            {
                Buttons.Add(new DialogButton(new DialogButton.Config()
                {
                    Text = "Ne",
                    Icon = Icon.Decline,
                    ButtonType = DialogButtons.No,
                    ID = String.Format("{0}No", ID)
                }));
            }

            if ((DialogButtons & DialogButtons.Save) == DialogButtons.Save)
            {
                Buttons.Add(new DialogButton(new DialogButton.Config()
                {
                    Text = "Shrani",
                    Icon = Icon.Disk,
                    ButtonType = DialogButtons.Save,
                    ID = String.Format("{0}Save", ID)
                }));
            }

            if ((DialogButtons & DialogButtons.Send) == DialogButtons.Send)
            {
                Buttons.Add(new DialogButton(new DialogButton.Config()
                {
                    Text = "Pošlji",
                    Icon = Icon.ArrowRight,
                    ButtonType = DialogButtons.Send,
                    ID = String.Format("{0}Send", ID)
                }));
            }

            if ((DialogButtons & DialogButtons.Cancel) == DialogButtons.Cancel)
            {
                Buttons.Add(new DialogButton(new DialogButton.Config()
                {
                    Text = "Prekliči",
                    Icon = Icon.Cancel,
                    ButtonType = DialogButtons.Cancel,
                    ID = String.Format("{0}Cancel", ID)
                }));
            }

            if ((DialogButtons & DialogButtons.Close) == DialogButtons.Close)
            {
                Buttons.Add(new DialogButton(new DialogButton.Config()
                {
                    Text = "Zapri",
                    Icon = Icon.StopRed,
                    ButtonType = DialogButtons.Close,
                    ID = String.Format("{0}Close", ID)
                }));
            }

            // add extra parameter to "buttonclick" event
            foreach (DialogButton btn in Buttons)
            {
                btn.DirectEvents.Click.Event += ButtonClick;
                btn.DirectEvents.Click.ExtraParams.Add(
                    new Parameter(
                        "buttonType",
                        btn.ButtonType.ToString()
                    )
                );
            }
        }

        protected void ButtonClick(object sender, DirectEventArgs e)
        {
            DialogButtons btn = (DialogButtons)Enum.Parse(typeof(DialogButtons), e.ExtraParams["buttonType"]);

            if ((btn & (DialogButtons.Cancel | DialogButtons.Close)) > 0)
            {
                this.Close();
            }

            if (DialogButtonClicked != null)
            {
                DialogButtonEventArgs args = new DialogButtonEventArgs(e.ExtraParams);

                DialogButtonClicked(this, args);

                e.ErrorMessage = args.ErrorMessage;
                e.Success = args.Success;
                e.ExtraParamsResponse.AddRange(args.ExtraParamsResponse);
            }
        }

        public delegate void OnDialogButtonClicked(object sender, DialogButtonEventArgs e);
        public event OnDialogButtonClicked DialogButtonClicked = null;
    }

    [Meta]
    public class DialogButton : Ext.Net.Button
    {
        public DialogButton(Config config)
            : base(config)
        {
            ButtonType = config.ButtonType;
            ID = config.ID;
        }

        private DialogButtons buttonType = DialogButtons.None;
        [Meta]
        [ConfigOption]
        public DialogButtons ButtonType
        {
            get
            {
                return buttonType;
            }
            set
            {
                buttonType = value;
            }
        }

        public override ConfigOptionsCollection ConfigOptions
        {
            get
            {
                ConfigOptionsCollection list = base.ConfigOptions;
                list.Add("buttonType", new ConfigOption("buttonType", new SerializationOptions("buttonType"), DialogButtons.None, ButtonType));
                return list;
            }
        }

        public new class Config : Button.Config
        {
            public Config()
            {
            }

            [DefaultValue(DialogButtons.None)]
            public DialogButtons ButtonType { get; set; }

            public string ID { get; set; }
        }
    }

    [Flags]
    public enum DialogButtons : int
    {
        None,
        Ok = 1,
        Cancel = 2,
        Yes = 4,
        No = 8,
        Close = 16,
        Save = 32,
        Send = 64,
        YesNo = Yes | No,
        OkCancel = Ok | Cancel,
        YesNoCancel = Yes | No | Cancel,
        SaveClose = Save | Close
    }

    public class DialogButtonEventArgs : DirectEventArgs
    {
        public DialogButtonEventArgs(ParameterCollection extraParams)
            : base(extraParams)
        {
        }

        private DialogButtons _button = DialogButtons.None;
        public DialogButtons Button
        {
            get
            {
                if (_button == DialogButtons.None && ExtraParams["buttonType"] != null)
                {
                    _button = (DialogButtons)Enum.Parse(typeof(DialogButtons), ExtraParams["buttonType"]);
                }

                return _button;
            }
        }
    }

    public class DialogProxy : WindowProxy
    {
        public void DisableButton(DialogButtons button)
        {
            DisableButton(button, true);
        }
        public void DisableButton(DialogButtons button, bool disable)
        {
            this.Call("disableButton", button, disable);
        }

        [Description("Send event / notification to parent window.")]
        public void CallParent(string parram)
        {
            this.Call("callParent");
        }
    }
}
